package com.vue.admin.service.common.mybatis.plugins;

import com.vue.admin.service.common.mybatis.entity.Page;
import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;

import java.sql.Statement;
import java.util.Properties;


/**
 * @program: tk-robot-service
 * @description:
 * @author: zhangyangyang
 * @create: 2020-01-07 10:26
 **/
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class PaginationResultSetHandlerInterceptor implements Interceptor {

	private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
	private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
	private static final ReflectorFactory DEFAULT_REFLECTOR_FACTORY = new DefaultReflectorFactory();

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		DefaultResultSetHandler resultSetHandler = (DefaultResultSetHandler)invocation.getTarget();
		MetaObject metaStatementHandler = MetaObject.forObject(resultSetHandler,
				PaginationResultSetHandlerInterceptor.DEFAULT_OBJECT_FACTORY,
				PaginationResultSetHandlerInterceptor.DEFAULT_OBJECT_WRAPPER_FACTORY,
				PaginationResultSetHandlerInterceptor.DEFAULT_REFLECTOR_FACTORY);
		RowBounds rowBounds = (RowBounds)metaStatementHandler.getValue("rowBounds");

		Object result = invocation.proceed();

		if(rowBounds instanceof Page) {
			metaStatementHandler.setValue("rowBounds.rows", result);
		}
		return result;
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {
	}

}
